package cn.openea.perpartner.common.core.utils;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.openea.perpartner.common.core.constant.DateConstant;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import java.util.Date;

/**
 * @author Weird077
 * @description TODO
 * @date 2022-01-24 17:43
 */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    public static String YYYY_MM_DD = "yyyy-MM-dd";
    public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    private static String[] parsePatterns = {
            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};

    /**
     * 获取当前日期
     *
     * @return
     */
    public static String getNow() {
        DateTimeFormatter fmTime = DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM_SS);
        LocalDateTime now = LocalDateTime.now();
        return now.format(fmTime);
    }

    public static Date parseDate(Object str) {
        if (str == null) {
            return null;
        }
        try {
            return parseDate(str.toString(), parsePatterns);
        } catch (ParseException e) {
            return null;
        }
    }

    public static String parseDateToStr(String format, Date date) {
        return new SimpleDateFormat(format).format(date);
    }

    public static Date toDate(LocalDateTime temporalAccessor) {
        ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
        return Date.from(zdt.toInstant());
    }

    /**
     * 增加 LocalDate ==> Date
     */
    public static Date toDate(LocalDate temporalAccessor) {
        LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
        ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
        return Date.from(zdt.toInstant());
    }

    public static Object datePath() {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyy/MM/dd");
    }

    public static final String dateTimeNow() {
        return dateTimeNow(YYYYMMDDHHMMSS);
    }

    public static final String dateTimeNow(final String format) {
        return parseDateToStr(format, new Date());
    }

    /**
     * 格式化时间为指定格式的字符串
     *
     * @param date    时间对像
     * @param formate 格式化字符串如：yyyy-MM-dd HH:mm:ss
     * @return 返回字符串
     */
    public static String formatDate(Date date, String formate) {
        try {
            SimpleDateFormat simpleDateFormate = new SimpleDateFormat(formate);
            return simpleDateFormate.format(date);
        } catch (Exception e) {
        }
        return "";
    }

    /**
     * 按要求格式化日期
     *
     * @param dateStr 时间格式字符串
     * @param sdf
     * @return
     */
    public static String formatDate(String dateStr, String sdf) {
        if (StringUtils.isBlank(dateStr) || StringUtils.isBlank(sdf)) {
            return "";
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(sdf);
        Date date = DateUtil.parse(dateStr);
        return simpleDateFormat.format(date);
    }

    /**
     * 将指定格式字符串转为日期
     */
    public static LocalDate formatLocalDate(String date, String formatStr) {
        if (StringUtils.isBlank(date)) {
            return null;
        }
        if (StringUtils.isBlank(formatStr)) {
            formatStr = DateConstant.DEFAULT_DATE_TIME_PATTERN;
        }
        LocalDateTime parse = LocalDateTime.parse(date, DateTimeFormatter.ofPattern(formatStr));
        return parse.toLocalDate();
    }

    /**
     * 计算两个日期之间相差的天数（不足一天按一天算）
     *
     * @param dateStr1
     * @param dateStr2
     * @return 相差天数
     * @throws ParseException
     */
    public static int daysBetween(String dateStr1, String dateStr2) throws ParseException {

        SimpleDateFormat sdf = new SimpleDateFormat(DateConstant.DEFAULT_DATE_TIME_PATTERN);

        Calendar cal = Calendar.getInstance();

        Date date1 = sdf.parse(dateStr1);
        Date date2 = sdf.parse(dateStr2);

        cal.setTime(date1);
        long time1 = cal.getTimeInMillis();

        cal.setTime(date2);
        long time2 = cal.getTimeInMillis();

        long time = Math.abs(time2 - time1);// 取绝对值

        long millisecond = 1000 * 3600 * 24;// 一天的毫秒值

        int between_days = 0;

        // 判断式：整除法
        if ((time % millisecond) == 0) {
            between_days = (int) (time / millisecond);
        } else {
            between_days = (int) (time / millisecond) + 1;
        }

        return between_days;
    }

    /**
     * 指定日期加上天数后的日期
     *
     * @param num     为增加的天数
     * @param newDate 创建时间
     * @return
     * @throws ParseException
     */
    public static String plusDay(int num, String newDate) throws ParseException {
        if (StringUtils.isBlank(newDate)) {
            throw new RuntimeException("newDate is not blank");
        }
        SimpleDateFormat format = new SimpleDateFormat(DateConstant.DEFAULT_DATE_TIME_PATTERN);
        Date currdate = format.parse(newDate);
        // BeanCtx.p("现在的日期是：" + currdate);
        Calendar ca = Calendar.getInstance();
        ca.setTime(currdate);
        ca.add(Calendar.DATE, num);// num为增加的天数，可以改变的
        Date d = ca.getTime();
        String enddate = format.format(d);
        return enddate;
    }

    /**
     * 判断当天是否为本月第一天
     *
     * @return
     */
    public static boolean isFirstDayOfMonth() {
        boolean flag = false;
        Calendar calendar = Calendar.getInstance();
        int today = calendar.get(calendar.DAY_OF_MONTH);
        if (1 == today) {
            flag = true;
        }
        return flag;
    }

    /**
     * 判断两个时间是否在24小时之类
     *
     * @param dateStr1 时间1 格式yyyy-MM-dd HH:mm:ss
     * @param dateStr2 时间2 格式yyyy-MM-dd HH:mm:ss
     * @return boolean
     */
    public static boolean within24Hours(String dateStr1, String dateStr2) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime dateTime1 = LocalDateTime.parse(dateStr1, formatter);
        LocalDateTime dateTime2 = LocalDateTime.parse(dateStr2, formatter);
        long hoursBetween = ChronoUnit.SECONDS.between(dateTime1, dateTime2);
        return Math.abs(hoursBetween) <= 86400;
    }

    /**
     * 判断两个时间是否在24小时之类
     *
     * @param dateTime1 时间1 格式yyyy-MM-dd HH:mm:ss
     * @param dateTime2 时间2 格式yyyy-MM-dd HH:mm:ss
     * @return boolean
     */
    public static boolean within24Hours(LocalDateTime dateTime1, LocalDateTime dateTime2) {
        long hoursBetween = ChronoUnit.SECONDS.between(dateTime1, dateTime2);
        return Math.abs(hoursBetween) <= 86400;
    }

    /**
     * 通过秒毫秒数判断两个时间的间隔的天数
     *
     * @param dateStr 格式 yyyy-MM-dd HH:mm:ss
     */
    public static String getDiffTime(String dateStr) throws ParseException {
        if (StringUtils.isBlank(dateStr)) {
            return "";
        }
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        ParsePosition pos = new ParsePosition(0);
        // 比较时间
        Date inTime = formatter.parse(dateStr, pos);
        return getDiffTime(inTime);
    }

    /**
     * 通过秒毫秒数判断两个时间的间隔的天数
     *
     * @param Date
     */
    public static String getDiffTime(Date inTime) {
        // 当前时间
        Date curTime = new Date();
        long timeDiff = curTime.getTime() - inTime.getTime();
        // 单位换算
        long sec = 1000;
        long min = 60 * 1000;
        long hour = min * 60;
        long day = hour * 24;
        long week = day * 7;
        long month = day * 30;
        long year = month * 12;
        DecimalFormat df = new DecimalFormat("#");

        // 计算发布时间距离当前时间的周、天、时、分
        double exceedyear = Math.floor(timeDiff / year);
        double exceedmonth = Math.floor(timeDiff / month);
        double exceedWeek = Math.floor(timeDiff / week);
        double exceedDay = Math.floor(timeDiff / day);
        double exceedHour = Math.floor(timeDiff / hour);
        double exceedMin = Math.floor(timeDiff / min);
        double exceedSec = Math.floor(timeDiff / sec);
        // 最后判断时间差到底是属于哪个区间，然后return
        if (exceedyear < 100 && exceedyear > 0) {
            return df.format(exceedyear) + "年前";
        } else {
            if (exceedmonth < 12 && exceedmonth > 0) {
                return df.format(exceedmonth) + "月前";
            } else {
                if (exceedWeek < 4 && exceedWeek > 0) {
                    return df.format(exceedWeek) + "星期前";
                } else {
                    if (exceedDay < 7 && exceedDay > 0) {
                        return df.format(exceedDay) + "天前";
                    } else {
                        if (exceedHour < 24 && exceedHour > 0) {
                            return df.format(exceedHour) + "小时前";
                        } else {
                            if (exceedMin < 60 && exceedMin > 0) {
                                return df.format(exceedMin) + "分钟前";
                            } else {
                                return df.format(exceedSec) + "秒前";
                            }
                        }
                    }
                }
            }
        }
    }
}
